package com.teamone.etl.apimanager.timer;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.teamone.etl.apimanager.dao.AlarmApiDao;
import com.teamone.etl.apimanager.dao.ApiDao;
import com.teamone.etl.apimanager.entity.AlarmApi;
import com.teamone.etl.apimanager.entity.Api;
import com.teamone.etl.enterprise.entity.AlarmPhone;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * @Description 
 * @Author WangZhuoRan
 * @Email  2908540863@qq.com
 * @Create 2021-01-21 20:57
 * @Program star-etl
 */
@Slf4j
@Component
public class AlarmTimer {

    @Resource
    private AlarmApiDao alarmApiDao;

    @Resource
    private ApiDao apiDao;

    private static Map<Integer, String> phoneMap;

    @Scheduled(cron = "0 0/6 * * * ?")
    public void getPhoneTimer (){
        Map<Integer, String> temp = new HashMap<>(64);
        List<AlarmPhone> alarmPhoneList = alarmApiDao.getAlarmPhoneList();

        for (AlarmPhone alarmPhone : alarmPhoneList) {
            temp.put(alarmPhone.getId(), alarmPhone.getPhone());
        }
        phoneMap=temp;
    }

    @Scheduled(cron = "0 0/10 * * * ?")
    public void countTimer (){
        List<AlarmApi> alarmList = alarmApiDao.getAlarmList();
        AlarmApi[] alarmArray = alarmList.toArray(new AlarmApi[0]);
        List<Api> apiList = apiDao.getNotDeleteApiList();
        Api[] apiArray = apiList.toArray(new Api[0]);

        ForkJoinPool forkJoinPool = new ForkJoinPool();
        AlarmForkJoinTask task = new AlarmForkJoinTask(alarmArray, apiArray);
        forkJoinPool.submit(task);

    }

    public static class AlarmForkJoinTask extends RecursiveAction {

        private static final int THRESHOLD = 20;
        private static final Integer COUNT_TYPE = 0;
        private static final Integer HOURS_TYPE = 1;
        private final AlarmApi[] alarmArray;
        private final Api[] apiArray;

        public AlarmForkJoinTask (AlarmApi[] alarmArray, Api[] apiArray) {
            this.alarmArray=alarmArray;
            this.apiArray=apiArray;
        }

        @Override
        protected void compute () {
            //条件
            boolean canComput = apiArray.length <= THRESHOLD;
            //判断执行or拆分
            if (canComput){
                Date nowDate = new Date();
                //循环api列表
                log.info(">>>>>>{}","循环api列表");
                for (Api api : apiArray) {
                    //循环预警表
                    log.info(">>>>>>{}","循环预警表");
                    for (AlarmApi alarmApi : alarmArray) {
                        if (alarmApi.getApiId().equals(api.getId())) {
                            //阈值
                            Integer threshold = alarmApi.getAlarmThreshold();
                            //判断预警类型
                            log.info(">>>>>>{}", "判断预警类型");
                            if (api.getHours() != null) {
                                long surplusHours = DateUtil.between(api.getCreateTime(), nowDate, DateUnit.HOUR);
                                //如果预警方式是时间 且 剩余时间小于阈值
                                log.info(">>>>>>{}", "如果预警方式是时间");
                                if (HOURS_TYPE.equals(alarmApi.getAlarmType()) && surplusHours <= threshold) {
                                    //发短信
                                    log.info("API{}到期- 时间 -发短信给{}",api.getId(),
                                            phoneMap.get(alarmApi.getAlarmPhoneId()));
                                }else if (api.getCount() <= threshold){
                                    //发短信
                                    log.info("API{}到期- 时间+次数 -发短信给{}",api.getId(),phoneMap.get(alarmApi.getAlarmPhoneId()));
                                }
                            } else {
                                //如果剩余次数小于阈值
                                if (COUNT_TYPE.equals(alarmApi.getAlarmType()) && api.getCount() <= threshold) {
                                    //发短信
                                    log.info("API{}到期- 次数 -发短信给{}",api.getId(),phoneMap.get(alarmApi.getAlarmPhoneId()));
                                }
                            }
                        }
                    }
                }
            }else{
                int middle = apiArray.length / 2;
                Api[] left = new Api[middle];
                System.arraycopy(apiArray, 0, left, 0, left.length);

                Api[] right = new Api[apiArray.length-middle];
                System.arraycopy(apiArray, middle, right, 0, right.length);

                AlarmForkJoinTask leftTask = new AlarmForkJoinTask(alarmArray, left);
                AlarmForkJoinTask rightTask = new AlarmForkJoinTask(alarmArray, right);

                leftTask.fork();
                rightTask.fork();

                leftTask.join();
                rightTask.join();
            }
        }
    }

}
